import mongoose, { Document, Schema } from 'mongoose';

export interface IOrderItem {
  product: mongoose.Types.ObjectId;
  quantity: number;
  price: number;
  attributes: Record<string, any>;
  name: string;
  image: string;
}

export interface IOrder extends Document {
  orderNumber: string;
  user: mongoose.Types.ObjectId;
  items: IOrderItem[];
  totalPrice: number;
  status: 'pending' | 'paid' | 'shipped' | 'delivered' | 'cancelled' | 'refunded';
  paymentMethod: 'alipay' | 'wechat' | 'creditcard' | 'cod';
  paymentStatus: 'pending' | 'paid' | 'failed' | 'refunded';
  paymentId: string;
  shippingAddress: {
    name: string;
    phone: string;
    province: string;
    city: string;
    district: string;
    address: string;
    zipcode: string;
  };
  shippingMethod: string;
  shippingFee: number;
  shippingCompany: string;
  trackingNumber: string;
  discount: number;
  note: string;
  refundReason: string;
  createdAt: Date;
  updatedAt: Date;
  paidAt: Date;
  shippedAt: Date;
  deliveredAt: Date;
  cancelledAt: Date;
  refundedAt: Date;
}

const OrderSchema: Schema = new Schema(
  {
    orderNumber: {
      type: String,
      required: true,
      unique: true,
    },
    user: {
      type: Schema.Types.ObjectId,
      ref: 'User',
      required: true,
    },
    items: [
      {
        product: {
          type: Schema.Types.ObjectId,
          ref: 'Product',
          required: true,
        },
        quantity: {
          type: Number,
          required: true,
          min: 1,
        },
        price: {
          type: Number,
          required: true,
        },
        attributes: {
          type: Map,
          of: Schema.Types.Mixed,
          default: {},
        },
        name: String,
        image: String,
      },
    ],
    totalPrice: {
      type: Number,
      required: true,
      min: 0,
    },
    status: {
      type: String,
      enum: ['pending', 'paid', 'shipped', 'delivered', 'cancelled', 'refunded'],
      default: 'pending',
    },
    paymentMethod: {
      type: String,
      enum: ['alipay', 'wechat', 'creditcard', 'cod'],
      required: true,
    },
    paymentStatus: {
      type: String,
      enum: ['pending', 'paid', 'failed', 'refunded'],
      default: 'pending',
    },
    paymentId: {
      type: String,
      default: '',
    },
    shippingAddress: {
      name: {
        type: String,
        required: true,
      },
      phone: {
        type: String,
        required: true,
      },
      province: {
        type: String,
        required: true,
      },
      city: {
        type: String,
        required: true,
      },
      district: {
        type: String,
        required: true,
      },
      address: {
        type: String,
        required: true,
      },
      zipcode: String,
    },
    shippingMethod: {
      type: String,
      default: '普通快递',
    },
    shippingFee: {
      type: Number,
      default: 0,
    },
    shippingCompany: {
      type: String,
      default: '',
    },
    trackingNumber: {
      type: String,
      default: '',
    },
    discount: {
      type: Number,
      default: 0,
    },
    note: {
      type: String,
      default: '',
    },
    refundReason: {
      type: String,
      default: '',
    },
    paidAt: Date,
    shippedAt: Date,
    deliveredAt: Date,
    cancelledAt: Date,
    refundedAt: Date,
  },
  {
    timestamps: true,
  }
);

// 创建索引以提高查询性能
OrderSchema.index({ orderNumber: 1 });
OrderSchema.index({ user: 1 });
OrderSchema.index({ status: 1 });
OrderSchema.index({ createdAt: -1 });

// 生成订单号
OrderSchema.pre('save', function (next) {
  if (this.isNew) {
    const now = new Date();
    const year = now.getFullYear().toString().slice(-2);
    const month = (now.getMonth() + 1).toString().padStart(2, '0');
    const day = now.getDate().toString().padStart(2, '0');
    const hour = now.getHours().toString().padStart(2, '0');
    const minute = now.getMinutes().toString().padStart(2, '0');
    const second = now.getSeconds().toString().padStart(2, '0');
    const random = Math.floor(Math.random() * 1000).toString().padStart(3, '0');
    
    this.orderNumber = `O${year}${month}${day}${hour}${minute}${second}${random}`;
  }
  next();
});

export default mongoose.model<IOrder>('Order', OrderSchema); 